﻿using BepuPhysics.Constraints;

namespace Prowl.Runtime;


[AddComponentMenu($"{Prowl.Icons.FontAwesome6.HillRockslide}  Physics/{Prowl.Icons.FontAwesome6.Joint}  Constraints/{Prowl.Icons.FontAwesome6.LinesLeaning}  One Body Angular Servo")]
public sealed class OneBodyAngularServoConstraintComponent : OneBodyConstraintComponent<OneBodyAngularServo>
{
    [SerializeField, HideInInspector] private Quaternion _targetOrientation = Quaternion.identity;

    [SerializeField, HideInInspector] private float _targetOffset;
    [SerializeField, HideInInspector] private float _servoMaximumSpeed = 10;
    [SerializeField, HideInInspector] private float _servoBaseSpeed = 1;
    [SerializeField, HideInInspector] private float _servoMaximumForce = 1000;

    [SerializeField, HideInInspector] private float _springFrequency = 35;
    [SerializeField, HideInInspector] private float _springDampingRatio = 5;

    [ShowInInspector]
    public Quaternion TargetOrientation
    {
        get
        {
            return _targetOrientation;
        }
        set
        {
            _targetOrientation = value;
            ConstraintData?.TryUpdateDescription();
        }
    }

    [ShowInInspector]
    public float ServoMaximumSpeed {
        get {
            return _servoMaximumSpeed;
        }
        set {
            _servoMaximumSpeed = value;
            ConstraintData?.TryUpdateDescription();
        }
    }

    [ShowInInspector]
    public float ServoBaseSpeed {
        get {
            return _servoBaseSpeed;
        }
        set {
            _servoBaseSpeed = value;
            ConstraintData?.TryUpdateDescription();
        }
    }

    [ShowInInspector]
    public float ServoMaximumForce {
        get {
            return _servoMaximumForce;
        }
        set {
            _servoMaximumForce = value;
            ConstraintData?.TryUpdateDescription();
        }
    }

    [ShowInInspector]
    public float SpringFrequency {
        get {
            return _springFrequency;
        }
        set {
            _springFrequency = value;
            ConstraintData?.TryUpdateDescription();
        }
    }

    [ShowInInspector]
    public float SpringDampingRatio {
        get {
            return _springDampingRatio;
        }
        set {
            _springDampingRatio = value;
            ConstraintData?.TryUpdateDescription();
        }
    }

    internal override OneBodyAngularServo CreateConstraint()
    {
        return new OneBodyAngularServo {
            TargetOrientation = _targetOrientation,
            ServoSettings = new ServoSettings(_servoMaximumSpeed, _servoBaseSpeed, _servoMaximumForce),
            SpringSettings = new SpringSettings(_springFrequency, _springDampingRatio)
        };
    }
}